package de.g18.gruppe3.gui.controller;

import java.awt.FileDialog;
import java.awt.event.ActionEvent;
import java.util.List;

import javax.swing.JOptionPane;
import de.g18.gruppe3.common.exception.InvalidDataException;
import de.g18.gruppe3.common.exception.SQLServiceException;
import de.g18.gruppe3.common.model.OrganizationalUnit;
import de.g18.gruppe3.common.model.User;
import de.g18.gruppe3.dataio.service.provider.DataIOServiceProvider;
import de.g18.gruppe3.gui.helper.AbstractAction;
import de.g18.gruppe3.gui.view.UMView;
import de.g18.gruppe3.ldapinterface.service.provider.LDAPServiceProvider;

public class UMViewController {

	//Membervariabeln
	private final UMView view;
	private final UserController userController;
	private User user;
	private FileDialog fileDialog;
	private String filePath;
	private SqlConnectionViewController sqlConnectionViewController;
	private static final DataIOServiceProvider userDataIOServiceProvider = DataIOServiceProvider.getInstance();
	
	//Konstruktor
	public UMViewController(UserController uController) {
		userController = uController;
		view = new UMView("Benutzer anlegen");
		initializeComponents();
	}
	
	// Initialisierung der Componenten
	private void initializeComponents() {
		view.getbUCTopFilePath().addActionListener(new SetFilePath());
		view.getbUCTopFile().addActionListener(new AddUserFile());
		view.getbUCTopSqlPath().addActionListener(new SetSqlPath());
		view.getbUCTopSql().addActionListener(new AddUserSql());
		view.getbUCBottomFile().addActionListener(new AddFileAd());
		view.getbUCBottomSql().addActionListener(new AddSqlAd());
	}
	
	//Methode zum erzeugen neuer User.
	//Die Eigenschaften werden aus der View ins User-Objekt geschrieben
	private User newUser() throws InvalidDataException {
		user = new User();
		if (!view.gettfUCLogin().getText().isEmpty() &&
			!view.gettfUCVorName().getText().isEmpty() &&
			!view.gettfUCNachName().getText().isEmpty() &&
			!view.gettfUCGruppe().getText().isEmpty() &&
			view.getpfUCPasswort().getPassword().length > 0) {

			user.setLogin(view.gettfUCLogin().getText());
			user.setVorname(view.gettfUCVorName().getText());
			user.setNachname(view.gettfUCNachName().getText());
			user.setOU(new OrganizationalUnit(view.gettfUCGruppe().getText()));
			user.setPasswort(new String(view.getpfUCPasswort().getPassword()));
			
			return user;
		}
		throw new InvalidDataException();
	}
	
	//Mehtode zum leeren der Textfelder der GUI
	private void emptyTextFields() {
		view.gettfUCLogin().setText(null);
		view.gettfUCVorName().setText(null);
		view.gettfUCNachName().setText(null);
		view.gettfUCGruppe().setText(null);
		view.getpfUCPasswort().setText(null);
	}
	
	//Getter
	public String getFilePath() {
		return filePath;
	}

	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}

	//Subclasses
	private class SetFilePath extends AbstractAction {

		@Override
		protected void execute(ActionEvent aEvent) throws Exception {
			fileDialog = new FileDialog(view);
			fileDialog.setVisible(true);
			setFilePath(fileDialog.getDirectory() + fileDialog.getFile());
		}

	}

	private class AddUserFile extends AbstractAction {

		@Override
		protected void execute(ActionEvent aEvent) throws Exception {
			userController.AddUserToFile(newUser(), getFilePath());
			JOptionPane.showMessageDialog(null, "Benutzer wurde angelegt!");
			emptyTextFields();
		}

	}
	
	private class SetSqlPath extends AbstractAction {

		@Override
		protected void execute(ActionEvent aEvent) throws Exception {
			sqlConnectionViewController = new SqlConnectionViewController();
		}

	}


	private class AddUserSql extends AbstractAction {

		@Override
		protected void execute(ActionEvent aEvent) throws Exception {
			if (sqlConnectionViewController == null) {
				throw new SQLServiceException("SQLContext wurde noch nicht erstellt!", null);
			}
			userController.AddUserToSql(sqlConnectionViewController.getSqlPath(), sqlConnectionViewController.getSqlLogin(), sqlConnectionViewController.getSqlPassword(), newUser());
			JOptionPane.showMessageDialog(null, "Benutzer wurde angelegt!");
			emptyTextFields();
		}

	}
	
	private class AddFileAd extends AbstractAction {

		@Override
		protected void execute(ActionEvent aEvent) throws Exception {
			if (filePath == null) {
				fileDialog = new FileDialog(view);
				fileDialog.setVisible(true);
				setFilePath(fileDialog.getDirectory() + fileDialog.getFile());
			}
			List<User> vorhandeneUser = userDataIOServiceProvider.getCSVImportService().importUserCSV(filePath, ";");
			int option = JOptionPane.showConfirmDialog(view, "Sollen " + vorhandeneUser.size() + " Benutzer mit dem AD synchronisiert werden?",
										  			   "Achtung!", JOptionPane.YES_NO_CANCEL_OPTION);
			if (option != JOptionPane.YES_OPTION) {
				JOptionPane.showMessageDialog(view, "Synchronisation abgebrochen");
				return;
			}
			LDAPServiceProvider.getInstance().getLDAPSynchronizationService().synchronize(vorhandeneUser);
			JOptionPane.showMessageDialog(view, "Active Directory wurde synchronisiert.");
		}

	}
	
	private class AddSqlAd extends AbstractAction {

		@Override
		protected void execute(ActionEvent aEvent) throws Exception {
			List<User> vorhandeneUser = userDataIOServiceProvider.getSQLImportService().importUserSQL(sqlConnectionViewController.getSqlPath(), sqlConnectionViewController.getSqlLogin(), sqlConnectionViewController.getSqlPassword());
			LDAPServiceProvider.getInstance().getLDAPSynchronizationService().synchronize(vorhandeneUser);
			JOptionPane.showMessageDialog(view, "Active Directory wurde synchronisiert.");
		}

	}

}
